package genetischeralgorithmus;

import java.util.*;
import java.awt.*;
import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Dominik
 */
public class Selection {

    Parameter param;

    public Selection(Parameter param) {
        this.param = param;
    }

    public double[][] getRankingArray(LinkedList<Double> fitnessList) {

        double[][] rankinArray = new double[fitnessList.size()][2];

        for (int k = 0; k < fitnessList.size(); k++) {
            rankinArray[k][0] = fitnessList.get(k); //ueberfuehren in ein Array um Zugriffsgeschwindigkeit zu erhoehen
            rankinArray[k][1] = k;
        }

        quicksort(rankinArray, 0, rankinArray.length - 1);

        return rankinArray;


    }

    public Entity[][] getRoulettePairs(double[][] rankingArray, Population pop, int newEntityCount, double worstDistance) {

        double[] relativeFitnessArray = new double[rankingArray.length];
        double totalFitness = 0;
        Entity[][] roulettePairs = new Entity[newEntityCount][2];

        //an dieser Stelle wird für jede Entity die relative Fitness zur schlechtesten Loesung berechnet
        //dadurch soll der Effekt der Bestenselektion noch verstaerkt werden.
        for (int i = 0; i < rankingArray.length; i++) {
            relativeFitnessArray[i] = Math.abs(rankingArray[i][0] - worstDistance);
            totalFitness += relativeFitnessArray[i];
        }

        if (totalFitness < 1.0) {
            totalFitness =1;
        }
        Random rand1 = new Random();
        for (int i = 0; i < newEntityCount; i++) {

            //Rien ne va plus

            int whiteBall = rand1.nextInt((int) totalFitness);

            double currentFitness = 0;
            int j = 0;

            do {
                currentFitness += relativeFitnessArray[j];
                j++;
            } while (currentFitness < whiteBall && rankingArray.length > j);

            roulettePairs[i][0] = pop.getEntities()[(int) rankingArray[j - 1][1]]; //erste Entitaet eintragen

            whiteBall = rand1.nextInt((int) totalFitness);

            currentFitness = 0;
            j = 0;

            do {
                currentFitness += relativeFitnessArray[j];
                j++;
            } while (currentFitness < whiteBall && rankingArray.length > j);


            roulettePairs[i][1] = pop.getEntities()[(int) rankingArray[j - 1][1]]; //zweite Entitaet eintragen


        }





        return roulettePairs;
    }

    public Entity[][] getBestPairs(double[][] rankingArray, Population pop, int newEntityCount, double worstDistance){



        return null;
    }

    public void quicksort(double[][] array, int le, int ri) {
        int lo = le, hi = ri;
        if (hi > lo) {
            double mid = array[(int) ((lo + hi) / 2)][0];
            while (lo <= hi) {
                while (lo < ri && array[lo][0] < mid) {
                    ++lo;
                }
                while (hi > le && array[hi][0] > mid) {
                    --hi;
                }
                if (lo <= hi) {
                    double[] temp = new double[2];
                    temp[0] = array[lo][0];
                    temp[1] = array[lo][1];
                    array[lo] = array[hi];
                    array[hi] = temp;
                    ++lo;
                    --hi;
                }
            }
            if (le < hi) {
                quicksort(array, le, hi);
            }
            if (lo < ri) {
                quicksort(array, lo, ri);
            }
        }
    }
}






